/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package argentracker.activeentity.registry;

import com.google.appengine.api.datastore.Entity;

import argentracker.activeentity.ActiveEntity;
import argentracker.activeentity.exceptions.UnknownActiveEntityClassException;
import argentracker.activeentity.metadata.ActiveEntityMetadata;

/**
 * briefly description.
 * 
 * extense description.
 * 
 * @author matero (matero _at_ gmail _dot_ com)
 */
public interface ActiveEntityRegistryStrategy {

    /**
     * Checks if a class represents an ActiveEntity.
     * 
     * @param clazz
     *            Class to be verified.
     * @return <code>true</code> if instances of clazz are active entities; <code>false</code> in other way.
     */
    boolean isActiveEntityDefinedOn(Class<?> clazz);

    /**
     * Register the metadata of an ActiveEntity class.
     * 
     * @param aeClass
     *            Class which metadata must be registered.
     */
    <AE extends ActiveEntity<AE>> void registerActiveEntity(Class<AE> object);

    /**
     * Verifies if the registry knows the active entity class or not.
     * 
     * @param aeClass
     *            Class which must be validated.
     * @return <code>true</code> if the registry has metadata about the class; <code>false</code> in other way.
     */
    <AE extends ActiveEntity<AE>> boolean hasMetadataOf(Class<AE> aeClass);

    ActiveEntityMetadata<?> getActiveEntityMetadata(String className);
    
    /**
     * Gets the Active Entity Metadata.
     * 
     * @param <AE>
     *            Active Entity
     * @param aeClass
     *            the class for which the metadata is defined
     * @return a <em>not null</em> {@link ActiveEntityMetadata} corresponding to aeClass.
     * @throws UnknownActiveEntityClassException
     *             if no metadata is registered for aeClass.
     */
    <AE extends ActiveEntity<AE>> ActiveEntityMetadata<AE> getActiveEntityMetadata(Class<AE> aeClass)
            throws UnknownActiveEntityClassException;

    /**
     * Gets the Active Entity Metadata.
     * 
     * @param <AE>
     *            Active Entity
     * @param aeClass
     *            the class for which the metadata is defined
     * @return a <em>not null</em> {@link ActiveEntityMetadata} corresponding to aeClass, if no metadata is known for
     *         aeClass, it registers aeClass and then returns its metadata.
     */
    <AE extends ActiveEntity<AE>> ActiveEntityMetadata<AE> installActiveEntity(Class<AE> aeClass);

    <AE extends ActiveEntity<AE>> AE createActiveEntityFrom(Entity e, Class<AE> aeClass);


}
